/**
 * Copyright(c) 2010 Ceno Techonologies Co., Ltd.
 *
 * History:
 *   15-6-3 下午3:49 Created by lyyang
 */
package com.xunton.bss.weixin.api.message.event;

import java.io.StringReader;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import com.xunton.bss.weixin.api.Utils;
import com.xunton.bss.weixin.api.WeixinException;

/**
 * 事件工厂
 *
 * @author <a href="mailto:lyyang@ceno.cn">lyyang</a>
 * @version 1.0 15-6-3 下午3:49
 */
public class EventManager<E extends Event>
{
    private HashMap<String, String> events = new HashMap<String, String>();
    private HashMap<String, Listener> listeners = new HashMap<String, Listener>();

    public HashMap<String, String> getEvents()
    {
        return events;
    }

    public void setEvents(HashMap<String, String> events)
    {
        this.events = events;
    }

    public HashMap<String, Listener> getListeners()
    {
        return listeners;
    }

    public void setListeners(HashMap<String, Listener> listeners)
    {
        this.listeners = listeners;
    }

    public void acceptEvent(String xml)
            throws Exception
    {

        CommonEvent commonEvent = (CommonEvent) parse(xml, CommonEvent.class);
        String className = events.get(commonEvent.getEvent());
        Event event = null;
        if (className == null) {
            commonEvent.setXmlStr(xml);
            event = commonEvent;
        }
        else {
            Class classz = Class.forName(className);
            event = parse(xml, classz);
        }
        Listener listener =
                listeners.get(event.getType()) == null ? listeners.get("default") : listeners.get(event.getType());
        if (listener == null) {
            throw new WeixinException("err.bss.weixin.listener_not_found", "Can't find listener for message type " + event.getType());
        }
        listener.process(event);
    }

    public E parse(String xmlStr, Class classz)
            throws Exception
    {
        JAXBContext context = JAXBContext.newInstance(classz);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        StringReader reader = new StringReader(xmlStr);
        return (E) unmarshaller.unmarshal(reader);
    }

    public static void main(String[] args)
    {
//        try{
//            String xml = "<xml><ToUserName><![CDATA[gh_344333f49bae]]></ToUserName>\n" +
//                         "<FromUserName><![CDATA[oCi76t5vtZttO57dyX7q1P3_5S6Q]]></FromUserName>\n" +
//                         "<CreateTime>1433398038</CreateTime>\n" + "<MsgType><![CDATA[event]]></MsgType>\n" +
//                         "<Event><![CDATA[user_del_card]]></Event>\n" +
//                         "<CardId><![CDATA[pCi76tyWPrEo1c-qS-Fo_W2rtu9k]]></CardId>\n" +
//                         "<UserCardCode><![CDATA[870686964392]]></UserCardCode>\n" + "</xml>";
//           JAXBContext context = JAXBContext.newInstance(UserDelCardEvent.class);
//        Unmarshaller unmarshaller = context.createUnmarshaller();
//        StringReader reader = new StringReader(xml);
//            UserDelCardEvent obj = (UserDelCardEvent)unmarshaller.unmarshal(reader);
//            System.out.println(obj);
//        }
//        catch(Exception ex){
//            ex.printStackTrace();
//        }


        try {
            HashMap map = new HashMap();
            map.put("appid", "wxd930ea5d5a258f4f");
            map.put("mch_id", 10000100);
            map.put("device_info", 1000);
            map.put("body", "test");
            map.put("nonce_str", "ibuaiVcKdpRxkhJA");
            String[] keys = (String[]) map.keySet().toArray(new String[0]);
            Arrays.sort(keys);
            String tmp = "";
            for (String key : keys) {
                tmp += "&" + key + "=" + map.get(key);
            }
            tmp = tmp.substring(1) + "&key=192006250b4c09247ec02edce69f6a2d";
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(tmp.getBytes());
            String result = Utils.bytes2Hex(md.digest());
            System.out.println(result.toUpperCase());


        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
